home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / vga_card.000 / vga_cardgames-1.3.1.tar / vga_cardgames / ohhell.c < prev    next >
C/C++ Source or Header  |  1994-05-05  |  10KB  |  454 lines

  1. /*
  2.  * Oh Hell!
  3.  *
  4.  * Copyright (C) Evan Harris, 1991, 1993, 1994
  5.  *
  6.  * Permission is granted to freely redistribute and modify this code,
  7.  * providing the author(s) get credit for having written it.
  8.  */
  9.  
  10. #include <stdlib.h>
  11. #ifdef PRINTPROGRESS
  12. #include <stdio.h>
  13. #endif
  14. #include "ohhell.h"
  15.  
  16. unsigned char hand[NUMPLAYERS][NUMHANDS];
  17. unsigned char bid[NUMPLAYERS];
  18. unsigned char wins[NUMPLAYERS];
  19. unsigned char score[NUMPLAYERS];
  20. unsigned char played[NUMPLAYERS];
  21. unsigned char trumps;
  22. unsigned char led;
  23.  
  24.  
  25. void
  26. main(int argc, char **argv)
  27. {
  28.     unsigned char deal = 1;
  29.     unsigned char first = 0;
  30.  
  31.     InitDisplay(argc, argv);
  32.     InitRandom(NEW);
  33.     InitGame();
  34.  
  35.     for (;;) {
  36.     switch (PlayGame(deal, first)) {
  37.       case NEWGAME:
  38.         InitGame();
  39.         deal = 1;
  40.         first = (first + 1) % NUMPLAYERS;
  41.         break;
  42.       case NEXTGAME:
  43.         deal++;
  44.         first = (first + 1) % NUMPLAYERS;
  45.         break;
  46.       case QUIT:
  47.         EndDisplay();
  48.         exit(0);
  49.         break;
  50.     }
  51.     }
  52.  
  53. }
  54.  
  55.  
  56. void
  57. InitGame()
  58. {
  59.     unsigned char i;
  60.   
  61.     for (i = 0; i < NUMPLAYERS; i++)
  62.     score[i] = 0;
  63.     ShowScores(score);
  64.   
  65.     return;
  66. }
  67.  
  68.  
  69. short
  70. PlayGame(unsigned char deal, unsigned char first)
  71. {
  72.     unsigned char i, j;
  73.     short b, best;
  74.     short key;
  75.     short cmd;
  76.     unsigned char lead = first;
  77.  
  78.     if (deal > NUMHANDS) {
  79.     do {
  80.         cmd = GetCmd();
  81.     }
  82.     while (cmd != NEWGAME && cmd != QUIT);
  83.     return cmd;
  84.     }
  85.  
  86.     trumps = Deal(deal);
  87.  
  88.     for (i = 0; i < NUMPLAYERS; i++) {
  89.     wins[i] = 0;
  90.     }
  91.     ShowWins(wins);
  92.  
  93.     RemoveBids();
  94.     for (i = first; i < first + NUMPLAYERS; i++) {
  95.     b = GetBid(i % NUMPLAYERS, deal, first);
  96.     if (b == NEWGAME || b == QUIT) return b;
  97.     bid[i % NUMPLAYERS] = b;
  98.     ShowBid(bid[i % NUMPLAYERS], i % NUMPLAYERS);
  99.     }
  100.  
  101.     for (i = 0; i < deal; i++) {
  102.     for (j = 0; j < NUMPLAYERS; j++) {
  103.         played[j] = NOCARD;
  104.     }
  105.     led = NOCARD;
  106.     for (j = lead; j < lead + NUMPLAYERS; j++) {
  107.         b = GetPlay(j % NUMPLAYERS, deal, lead);
  108.         if (b == NEWGAME || b == QUIT) return b;
  109.  
  110.         ShowPlay(b, j % NUMPLAYERS);
  111.         if (j % NUMPLAYERS == 0)
  112.         ShowHand(hand[0], deal);
  113.         played[j % NUMPLAYERS] = b;
  114.         if (led == NOCARD)
  115.         led = b;
  116.     }
  117.     best = -1;
  118.     for (j = lead; j < lead + NUMPLAYERS; j++) {
  119.         if (best == -1 || 
  120.         (SUIT(played[j % NUMPLAYERS]) == SUIT(played[best]) && 
  121.          (TYPE(played[j % NUMPLAYERS]) + 12) % 13 > 
  122.          (TYPE(played[best]) + 12) % 13) ||
  123.         (SUIT(played[j % NUMPLAYERS]) == trumps && 
  124.          SUIT(played[best]) != trumps)) {
  125.         best = j % NUMPLAYERS;
  126.         }
  127.     }
  128.     wins[best]++;
  129.     lead = best;
  130.     ShowWins(wins);
  131.     key = WaitForKey();
  132.     RemovePlays();
  133.     if (key != CONTINUE)
  134.         return key;
  135.     }
  136.   
  137.     for (i = 0; i < NUMPLAYERS; i++) {
  138.     if (wins[i] == bid[i])
  139.         score[i] += 10 + bid[i];
  140.     }
  141.     ShowScores(score);
  142.  
  143.     return NEXTGAME;
  144. }
  145.  
  146.  
  147. unsigned char
  148. Deal(unsigned char deal)
  149. {
  150.     unsigned char cards[NUMCARDS];
  151.     unsigned char i, j, k;
  152.     short r;
  153.   
  154.     for (i = 0; i < NUMCARDS; i++) {
  155.     cards[i] = 0;
  156.     }
  157.     for (i = 0; i < deal; i++) {
  158.     for (j = 0; j < NUMPLAYERS; j++) {
  159.         r = Random(NUMCARDS - (i * NUMPLAYERS + j));
  160.         for (k = 0; k < NUMCARDS && r >= 0; k++) {
  161.         if (cards[k] == 0)
  162.             r--;
  163.         }
  164.         r = k - 1;
  165.         cards[r] = 1;
  166.       
  167.         hand[j][i] = r;
  168.     }
  169.     }
  170.   
  171.     if (deal * NUMPLAYERS < NUMCARDS) {
  172.     r = Random(NUMCARDS - deal * NUMPLAYERS);
  173.     for (k = 0; k < NUMCARDS && r >= 0; k++) {
  174.         if (cards[k] == 0)
  175.         r--;
  176.     }
  177.     trumps = k - 1;
  178.  
  179.     ShowTrumps(trumps);
  180.     trumps = SUIT(trumps);
  181.     } 
  182.     else {
  183.     RemoveTrumps();
  184.     trumps = NOSUIT;
  185.     }
  186.  
  187.     qsort(hand[0], deal, sizeof(unsigned char), (__compar_fn_t)&Cmp);
  188.     ShowHand(hand[0], deal);
  189.  
  190.     return trumps;
  191. }
  192.  
  193.  
  194. short
  195. GetBid(unsigned char player, unsigned char deal, unsigned char first)
  196. {
  197.     short bid = 0;
  198.     unsigned char i, numtrumps = 0;
  199.  
  200.     if (player == 0)
  201.     return GetPlayerBid(deal);
  202.  
  203.     for (i = 0; i < deal; i++) {
  204.     if (TYPE(hand[player][i]) == ACE || TYPE(hand[player][i]) == KING ||
  205.         TYPE(hand[player][i]) == QUEEN)
  206.         bid++;
  207.     else if (SUIT(hand[player][i]) == trumps)
  208.         numtrumps++;
  209.     }
  210.  
  211.     if (deal < 4 && player == first)
  212.     bid++;
  213.     if (numtrumps > deal / 4)
  214.     bid += numtrumps - deal / 4;
  215.     if (bid > deal)
  216.     bid = deal;
  217.  
  218.     return bid;
  219. }
  220.  
  221.  
  222. short
  223. GetPlay(unsigned char player, unsigned char deal, unsigned char first)
  224. {
  225. #ifdef PRINTPROGRESS
  226.     static char suits[] = { 's', 'c', 'h', 'd' };
  227.     static char types[] = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
  228. #endif
  229.     short cmd = NOCARD, ret;
  230.     unsigned char i;
  231.     unsigned char best = NOCARD;
  232.     unsigned char wanttowin;
  233.     unsigned char winning;
  234.     short smallestwinner, biggestwinner, smallestloser, biggestloser;
  235.     unsigned char legal[NUMCARDS / NUMPLAYERS];
  236.     unsigned char numlegal;
  237.     unsigned char under, over, equal;
  238.  
  239.     if (player == 0) {
  240.     while (cmd == NOCARD) {
  241. #if 0
  242.         FlushIn();
  243. #endif
  244.         cmd = GetCmd();
  245.         if (cmd < 0)
  246.         return cmd;
  247.         else if (led != NOCARD && 
  248.              SUIT(hand[player][cmd]) != SUIT(led)) {
  249.         for (i = 0; i < deal; i++)
  250.             if (hand[player][i] != NOCARD &&
  251.             SUIT(hand[player][i]) == SUIT(led))
  252.             cmd = NOCARD;
  253.         }
  254.     }
  255.     ret = hand[player][cmd];
  256.     hand[player][cmd] = NOCARD;
  257.     return ret;
  258.     }
  259.  
  260. #ifdef PRINTPROGRESS
  261.     if (led == NOCARD) fprintf(stderr, "\n");
  262.     fprintf(stderr, "Player %d : ", player);
  263.     for (i = 0; i < deal; i++)
  264.     if (hand[player][i] != NOCARD)
  265.         fprintf(stderr, "%c%c ", types[TYPE(hand[player][i])],
  266.             suits[SUIT(hand[player][i])]);
  267. #endif
  268.  
  269.     if (led != NOCARD) {
  270.     /*
  271.      * Find which card that has been played is winning.
  272.      */
  273.     winning = led;
  274.     for (i = (first + 1) % NUMPLAYERS;
  275.          i != player;
  276.          i = (i + 1) % NUMPLAYERS) {
  277.         if ((SUIT(played[i]) == SUIT(winning)
  278.          && TYPECMP(played[i], winning) > 0) || 
  279.         (SUIT(played[i]) == trumps && SUIT(winning) != trumps))
  280.         winning = played[i];
  281.     }
  282.  
  283.     /*
  284.      * Find all the legal cards.  First a pass looking for suit cards.
  285.      */
  286.     numlegal = 0;
  287.     for (i = 0; i < deal; i++) {
  288.         if (hand[player][i] != NOCARD
  289.         && SUIT(hand[player][i]) == SUIT(led)) {
  290.         legal[numlegal] = i;
  291.         numlegal++;
  292.         }
  293.     }
  294.  
  295. #ifdef PRINTPROGRESS
  296.     fprintf(stderr, " legal : %d ", numlegal);
  297. #endif
  298.  
  299.     smallestloser = biggestloser = smallestwinner = biggestwinner = -1;
  300.     if (numlegal > 0) {
  301.         /*
  302.          * Look amongst suit cards for all winners and losers.
  303.          */
  304.         for (i = 0; i < numlegal; i++) {
  305.         if ((SUIT(led) == trumps || SUIT(winning) != trumps) && 
  306.             TYPECMP(winning, hand[player][legal[i]]) < 0) {
  307.             if (smallestwinner == -1)
  308.             smallestwinner = biggestwinner = legal[i];
  309.             else if (TYPECMP(hand[player][smallestwinner],
  310.                      hand[player][legal[i]]) > 0)
  311.             smallestwinner = legal[i];
  312.             else if (TYPECMP(hand[player][biggestwinner],
  313.                      hand[player][legal[i]]) < 0)
  314.             biggestwinner = legal[i];
  315.         } else {
  316.             if (smallestloser == -1)
  317.             smallestloser = biggestloser = legal[i];
  318.             else if (TYPECMP(hand[player][smallestloser],
  319.                      hand[player][legal[i]]) > 0)
  320.             smallestloser = legal[i];
  321.             else if (TYPECMP(hand[player][biggestloser],
  322.                      hand[player][legal[i]]) < 0)
  323.             biggestloser = legal[i];
  324.         }
  325.         }
  326.     } else {
  327.         /*
  328.          * Look amongst all cards for winners (trumps) and losers (others).
  329.          */
  330.         for (i = 0; i < deal; i++) {
  331.         if (hand[player][i] != NOCARD) {
  332.             if (SUIT(hand[player][i]) == trumps &&
  333.             (SUIT(winning) != trumps
  334.              || TYPECMP(winning, hand[player][i]) < 0)) {
  335.             if (smallestwinner == -1)
  336.                 smallestwinner = biggestwinner = i;
  337.             else if (TYPECMP(hand[player][smallestwinner],
  338.                      hand[player][i]) > 0)
  339.                 smallestwinner = i;
  340.             else if (TYPECMP(hand[player][biggestwinner],
  341.                      hand[player][i]) < 0)
  342.                 biggestwinner = i;
  343.             } 
  344.             else {
  345.             if (smallestloser == -1)
  346.                 smallestloser = biggestloser = i;
  347.             else if ((SUIT(hand[player][smallestloser]) == trumps
  348.                   && SUIT(hand[player][i]) != trumps)
  349.                  || TYPECMP(hand[player][smallestloser],
  350.                         hand[player][i]) > 0)
  351.                 smallestloser = i;
  352.             else if ((SUIT(hand[player][smallestloser]) != trumps
  353.                   && SUIT(hand[player][i]) == trumps)
  354.                  || TYPECMP(hand[player][biggestloser],
  355.                         hand[player][i]) < 0)
  356.                 biggestloser = i;
  357.             }
  358.         }
  359.         }
  360.     }
  361.     }
  362.  
  363.     under = over = equal = 0;
  364.     for (i = 0; i < NUMPLAYERS; i++) {
  365.     if (i != player) {
  366.         if (wins[player] < bid[player])
  367.         under++;
  368.         else if (wins[player] > bid[player])
  369.         over++;
  370.         else
  371.         equal++;
  372.     }
  373.     }
  374.  
  375.     if (wins[player] < bid[player])
  376.     wanttowin = TRUE;
  377.     else
  378.     wanttowin = FALSE;
  379.  
  380.     if (led == NOCARD) {
  381.     for (i = 0; i < deal; i++) {
  382.         if (hand[player][i] != NOCARD) {
  383.         if (best == NOCARD ||
  384.             (wanttowin &&
  385.              TYPECMP(hand[player][best], hand[player][i]) < 0) ||
  386.             (!wanttowin &&
  387.              TYPECMP(hand[player][best], hand[player][i]) > 0))
  388.             best = i;
  389.         }
  390.     }
  391.     }
  392.     else {
  393. #ifdef PRINTPROGRESS
  394.     if (smallestloser != -1)
  395.         fprintf(stderr, " sl : %c%c",
  396.             types[TYPE(hand[player][smallestloser])],
  397.             suits[SUIT(hand[player][smallestloser])]);
  398.     if (biggestloser != -1)
  399.         fprintf(stderr, " bl : %c%c",
  400.             types[TYPE(hand[player][biggestloser])],
  401.             suits[SUIT(hand[player][biggestloser])]);
  402.     if (smallestwinner != -1)
  403.         fprintf(stderr, " sw : %c%c",
  404.             types[TYPE(hand[player][smallestwinner])],
  405.             suits[SUIT(hand[player][smallestwinner])]);
  406.     if (biggestwinner != -1)
  407.         fprintf(stderr, " bw : %c%c ",
  408.             types[TYPE(hand[player][biggestwinner])],
  409.             suits[SUIT(hand[player][biggestwinner])]);
  410. #endif
  411.  
  412.     if (wanttowin) {
  413.         if (smallestwinner != -1) {
  414.         if (player == (first - 1 + NUMPLAYERS) % NUMPLAYERS)
  415.             best = smallestwinner;
  416.         else
  417.             best = biggestwinner;
  418.         }
  419.         else
  420.         best = smallestloser;
  421.     }
  422.     else {
  423.         if (biggestloser != -1)
  424.         best = biggestloser;
  425.         else if (equal >= under)
  426.         best = smallestwinner;
  427.         else
  428.         best = biggestwinner;
  429.     }
  430.     }
  431.  
  432. #ifdef PRINTPROGRESS
  433.     fprintf(stderr, " playing : %c%c\n", types[TYPE(hand[player][best])],
  434.         suits[SUIT(hand[player][best])]);
  435. #endif
  436.  
  437.     ret = hand[player][best];
  438.     hand[player][best] = NOCARD;
  439.  
  440.     return ret;
  441. }
  442.  
  443.  
  444. int Cmp(unsigned char *a, unsigned char *b)
  445. {
  446.     static unsigned char remap[4] = { 0, 2, 1, 3 };
  447.     unsigned char arank = CARD(remap[SUIT(*a)], (TYPE(*a) + 12) % 13);
  448.     unsigned char brank = CARD(remap[SUIT(*b)], (TYPE(*b) + 12) % 13);
  449.  
  450.     if (arank < brank) return 1;
  451.     if (arank > brank) return -1;
  452.     return 0;
  453. }
  454.